package jvDeformation.gui;

import java.awt.Button;
import java.awt.Checkbox;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Observable;
import java.util.Observer;

import jv.number.PuInteger;
import jv.object.PsUpdateIf;
import jvDeformation.JvDeformationDisplay;
import jvDeformation.JvDeformationDisplay.HandlerStatus;
import stegru.tools.syncfield.S_Reference;
import stegru.tools.syncfield.S_boolean;
import stegru.tools.syncfield.S_double;
import stegru.tools.syncfield.S_int;
import stegru.tools.syncfield.SyncFields;
import deformation.DeformationGenerator;
import deformation.DeformationGenerator.DeformationType;

public class JvDeformationDisplayPanel extends Panel implements ActionListener, Observer, PsUpdateIf, ItemListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Button bLoad;
	private ComboBox<DeformationType> deformationChoice;
	private RadioBox<JvDeformationDisplay.HandlerStatus> handlerStatus_RadioBox;
	private JvDeformationDisplay jvDeformationDisplay;
	private AlphaControler alphaValue;
	private PuInteger gridPointsX_Pu;
	private PuInteger gridPointsY_Pu;
	private  SyncFields  syncFields;
	private  S_double alpha;
	private  S_Reference<DeformationType> deformationType;
	private  S_Reference<HandlerStatus> handlerStatus;
	private S_int gridPointsX;
	private S_int gridPointsY;
	private S_boolean showGrid;
	private Checkbox showGrid_Box;
	
	public JvDeformationDisplayPanel(JvDeformationDisplay jvDeformationDisplay) {
		this.setJvDeformationDisplay(jvDeformationDisplay);
		generateButtons();
		addButtons();
	}

	public JvDeformationDisplayPanel() {
		generateButtons();
		addButtons();
	}

	private void generateButtons() {
		deformationChoice = new ComboBox<DeformationType>(
				DeformationGenerator.getAllDeformations());
		deformationChoice.addActionListener(this);
		bLoad = new Button("load new Image");
		bLoad.addActionListener(this);
		handlerStatus_RadioBox = new RadioBox<JvDeformationDisplay.HandlerStatus>(JvDeformationDisplay.HandlerStatus.values(), RadioBox.HORIZONTAL);
		handlerStatus_RadioBox.addActionListener(this);
		alphaValue = new AlphaControler();
		alphaValue.addActionListener(this);
		gridPointsX_Pu = new PuInteger("gridPointsX");
		gridPointsX_Pu.setBounds(2, 300);
		gridPointsX_Pu.addUpdateListener(this);
		gridPointsY_Pu = new PuInteger("gridPointsY");
		gridPointsY_Pu.setBounds(2, 300);
		gridPointsY_Pu.addUpdateListener(this);
		showGrid_Box = new Checkbox("Show Grid");
		showGrid_Box.addItemListener(this);
	}
	
	
	private void addButtons(){
		this.setLayout(new GridLayout(0,1));
		add(handlerStatus_RadioBox);
		add(deformationChoice.getComponent());
		add(alphaValue.getPanel());
		add(gridPointsX_Pu.getInfoPanel());
		add(gridPointsY_Pu.getInfoPanel());
		add(showGrid_Box);
	}
	
	

	@Override
	public void actionPerformed(ActionEvent event) {
		Object source = event.getSource();
		if (syncFields == null) {
			return;
		}
		if (source == deformationChoice) {
			alphaValue.setLineStatus(deformationChoice.getSelected().isLine());
			alpha.set(alphaValue.getValue());
			deformationType.set(deformationChoice.getSelected());
		}else if (source == handlerStatus_RadioBox) {
			alphaValue.setLineStatus(deformationType.get().isLine());
			handlerStatus.set(handlerStatus_RadioBox.getSelected());
		}else if (source == alphaValue) {
			alpha.set(alphaValue.getValue());
		}
	}

	public JvDeformationDisplay getJvDeformationDisplay() {
		return jvDeformationDisplay;
	}

	public void setJvDeformationDisplay(JvDeformationDisplay jvDeformationDisplay) {
		if (syncFields != null) {
			syncFields.deleteObserver(this);
		}
		this.jvDeformationDisplay = jvDeformationDisplay;
		updateReferences(jvDeformationDisplay);
		
		handlerStatus_RadioBox.setSelected(handlerStatus.get());
		deformationChoice.select(deformationType.get());
		alphaValue.setLineStatus(deformationType.get().isLine());
		alpha.set(alphaValue.getValue());
	}
	
	private void updateReferences(JvDeformationDisplay jvDeformationDisplay){
		syncFields = jvDeformationDisplay.syncFields;
		syncFields.addObserver(this);
		alpha = jvDeformationDisplay.alpha;
		deformationType = jvDeformationDisplay.deformationType;
		handlerStatus = jvDeformationDisplay.handlerStatus;
		gridPointsX = jvDeformationDisplay.gridPointsX;
		gridPointsX_Pu.setValue(gridPointsX.get());
		gridPointsY = jvDeformationDisplay.gridPointsY;
		gridPointsY_Pu.setValue(gridPointsY.get());
		showGrid = jvDeformationDisplay.showGrid;
		
	}

	PsUpdateIf parent;
	@Override
	public boolean update(Object event) {
		if (gridPointsX_Pu == event) {
			gridPointsX.set(gridPointsX_Pu.getValue());
		}else if (gridPointsY_Pu == event) {
			gridPointsY.set(gridPointsY_Pu.getValue());
		}
		if (parent != null) {
			return parent.update(event);
		}
		return false;
	}
	
	@Override
	public void setParent(PsUpdateIf parent) {
		this.parent = parent;
	}
	
	@Override
	public String getName() {
		return AlphaControler.class.getSimpleName();
	}
	
	@Override
	public PsUpdateIf getFather() {
		return parent;
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		// TODO Auto-generated method stub
		
	}
	

	@Override
	public void itemStateChanged(ItemEvent e) {
		Object src = e.getSource();
		if (src == showGrid_Box) {
			showGrid.set(showGrid_Box.getState());
		}
		
	}
}
